// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Kernels.h 168 2007-11-05 19:23:53Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/include/Kernels.h $
//
// Author(s)     : Naceur Meskini and Sylvain Pion
//=========================================================================

#ifndef CGAL_PYTHON_KERNELS_H
#define CGAL_PYTHON_KERNELS_H

// Here we include the kernels to be used when exposing CGAL classes.
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>

typedef CGAL::Exact_predicates_exact_constructions_kernel K;

// The main issue with kernels here is that some member functions return by
// value or by const reference, and this affects the Python bindings.
// Moreover, some of these changed between CGAL releases, and this also depends
// on which kernel.
// Here is some code that tries to accomodate things, at least for CGAL-3.2,
// CGAL-3.3, and for the Lazy_kernel or the old EPECK definition.

#include <CGAL/version.h>
#include <boost/python.hpp>

#if CGAL_VERSION_NR < 1030301000 // CGAL_VERSION_NUMBER(3, 3, 0) only works after 3.3...
#  define BEF_33(A, B) A
#else
#  define BEF_33(A, B) B
#endif

typedef boost::python::return_value_policy< boost::python::copy_const_reference >  by_cref;
typedef boost::python::default_call_policies                                       by_copy;       

template < typename T >
struct If_cref {
    typedef by_copy type;
};

template < typename T >
struct If_cref < const T& > {
    typedef by_cref type;
};

template <typename Functor, typename P1 = void, typename P2 = void,
	  typename P3 = void, typename P4 = void,
          typename P5 = void, typename P6 = void,
          typename P7 = void, typename P8 = void>
struct Value_or_cref
{
#if CGAL_VERSION_NR < 1030301000
    typedef by_cref type; // by default, the other few cases are fixed locally.
#else
    typedef typename If_cref<typename CGAL::Qualified_result_of<Functor, P1, P2, P3, P4, P5, P6, P7, P8> ::type > ::type  type;
#endif
};


// Work around for an issue with compare_y_at_x's static filters, and Alpha_shapes_2
// which used unqualified min and max.
//#if CGAL_VERSION_NR < 1030301000 || CGAL_VERSION_NR >= 1030401000 // || defined CGAL_DONT_USE_LAZY_KERNEL
namespace CGAL {
inline const CGAL::Lazy_exact_nt<CGAL::Gmpq>&
min(const CGAL::Lazy_exact_nt<CGAL::Gmpq>&a, const CGAL::Lazy_exact_nt<CGAL::Gmpq>&b)
{ return a<b ? a : b; }
	 
inline const CGAL::Lazy_exact_nt<CGAL::Gmpq>&
max(const CGAL::Lazy_exact_nt<CGAL::Gmpq>&a, const CGAL::Lazy_exact_nt<CGAL::Gmpq>&b)
{ return a<b ? b : a; }
}
//#endif

#endif // CGAL_PYTHON_KERNELS_H
